/*
 * acooly.cn Inc.
 * Copyright (c) 2016 All Rights Reserved.
 * create by zhangpu 
 * date:2016年4月1日
 *
 */
package com.acooly.module.openapi.client.provider.fuiou.marshall;

import com.acooly.core.utils.Encodes;
import com.acooly.core.utils.Reflections;
import com.acooly.core.utils.Strings;
import com.acooly.module.openapi.client.api.marshal.ApiMarshal;
import com.acooly.module.openapi.client.provider.fuiou.FuiouConstants;
import com.acooly.module.openapi.client.provider.fuiou.domain.FuiouRequest;
import com.acooly.module.openapi.client.provider.fuiou.message.FuiouRegRequest;
import com.acooly.module.openapi.client.provider.fuiou.support.FuiouAlias;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.Map;
import java.util.Set;

/**
 * @author zhangpu
 */
@Service
public class FuiouRequestMarshall extends FuiouMarshallSupport implements ApiMarshal<String, FuiouRequest> {

    private static final Logger logger = LoggerFactory.getLogger(FuiouRequestMarshall.class);

    @Override
    public String marshal(FuiouRequest source) {
        beforeMarshall(source);
        Map<String, String> requestData = Maps.newTreeMap();
        Map<String, String> signData = Maps.newTreeMap();
        Set<Field> fields = Reflections.getFields(source.getClass());
        String key = null;
        String value = null;
        for (Field field : fields) {
            FuiouAlias fuiouAlias = field.getAnnotation(FuiouAlias.class);
            if (fuiouAlias == null) {
                continue;
            }
            key = fuiouAlias.value();
            if (Strings.isBlank(key)) {
                key = field.getName();
            }
            value = convertString(Reflections.invokeGetter(source, field.getName()));
            if (fuiouAlias.sign()) {
                signData.put(key, value);
            }
            if (Strings.isNotBlank(value)) {
                requestData.put(key, value);
            }
        }
        StringBuilder sb = new StringBuilder();
        for (String v : signData.values()) {
            sb.append(Strings.trimToEmpty(v)).append(SPLIT_CHAR);
        }
        String waitForSign = sb.substring(0, sb.length() - 1);
        logger.debug("待签字符串:{}", waitForSign);
        String signature = doSign(waitForSign);
        requestData.put("signature", signature);
        logger.info("请求报文:{}", requestData);
        return doMarshall(requestData);
    }

    private String doMarshall(Map<String, String> requestData) {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : requestData.entrySet()) {
            sb.append(Strings.trimToEmpty(entry.getKey())).append("=")
                    .append(Encodes.urlEncode(Strings.trimToEmpty(entry.getValue()))).append("&");
        }
        return sb.substring(0, sb.length() - 1);
    }

    private String doSign(String waitForSign) {
        return getSignerFactory().getSigner(FuiouConstants.SIGNER_KEY).sign(waitForSign, getKeyPair());
    }

    private String convertString(Object object) {
        if (object == null) {
            return null;
        }
        return object.toString();
    }

    public static void main(String[] args) {
        FuiouRequestMarshall frm = new FuiouRequestMarshall();
        FuiouRegRequest request = new FuiouRegRequest();
        request.setService("reg.action");
        request.setBankNm("BOC");
        request.setCapAcntNm("王丽");
        request.setCapAcntNo("6225887846374673");
        request.setCertifId("5103223895843723857X");
        request.setCertifTp("0");
        request.setCustNm("wangli");
        request.setEmail("wangli@163.com");
        request.setLpassword("111111");
        request.setMobileNo("13897617637");
        request.setParentBankId("0001");
        request.setPartner("123412342134");
        request.setPassword("222222");
        request.setRem("1111");
        System.out.println(frm.marshal(request));

    }

}
